package net.ericaro.neojavagengen;

import net.ericaro.neojavagen.Literals;
import net.ericaro.neojavagen.classes.ClassBody;
import net.ericaro.neojavagen.classes.ClassBodyDeclarations;
import net.ericaro.neojavagen.classes.ClassModifier;
import net.ericaro.neojavagen.classes.ClassModifiers;
import net.ericaro.neojavagen.classes.ConstructorBody;
import net.ericaro.neojavagen.classes.ConstructorDeclaration;
import net.ericaro.neojavagen.classes.ConstructorDeclarator;
import net.ericaro.neojavagen.classes.ConstructorModifier;
import net.ericaro.neojavagen.classes.ConstructorModifiers;
import net.ericaro.neojavagen.classes.FormalParameter;
import net.ericaro.neojavagen.classes.FormalParameters;
import net.ericaro.neojavagen.classes.InterfaceTypes;
import net.ericaro.neojavagen.classes.Interfaces;
import net.ericaro.neojavagen.classes.NormalClassDeclaration;
import net.ericaro.neojavagen.classes.Super;
import net.ericaro.neojavagen.classes.SuperExplicitConstructorInvocation;
import net.ericaro.neojavagen.classes.VariableDeclaratorId;
import net.ericaro.neojavagen.expressions.Arguments;
import net.ericaro.neojavagen.packages.TypeDeclaration;
import net.ericaro.neojavagen.types.ClassOrInterfaceType;
import net.ericaro.neojavagen.types.ClassType;
import net.ericaro.neojavagen.types.Identifier;
import net.ericaro.neojavagen.types.TypeArguments;
import net.ericaro.neojavagen.types.TypedIdentifier;


public class MetaList extends Meta {

	String divider,startSymbol, endSymbol;
	private MetaType target;
	
	
	public MetaList(Grammar grammar, String name, String divider, String startSymbol, String endSymbol, String referencedType) {
		super(grammar, name);
		this.divider = divider;
		this.startSymbol = startSymbol;
		this.endSymbol = endSymbol;
		this.target = grammar.createMetaType(referencedType);
	}
	@Override
	protected TypeDeclaration getTypeDeclaration() {
		ClassBodyDeclarations classBodyDeclarations = new ClassBodyDeclarations();
		
		ClassOrInterfaceType partList = new ClassOrInterfaceType();
		for (String i : "net/ericaro/neojavagen/JavaPartList".split("/"))
			partList.add(new TypedIdentifier( Literals.identifier(i), new TypeArguments(target.getClassOrInterfaceType())));
		
		// add constructors void, and P... parts
		//public ClassBodyDeclarations(net .ericaro .neojavagen .classes .ClassBodyDeclaration... parts){
		//   super(",",null,null, parts);
	   
		
		Identifier partsId = Literals.identifier("parts");
Arguments args = new Arguments(
				
				Grammar.unaryExpression(Literals.stringLiteral(divider)),
				Grammar.unaryExpression(Literals.stringLiteral(startSymbol)),
				Grammar.unaryExpression(Literals.stringLiteral(endSymbol)),
				Grammar.unaryExpression(partsId)
		);
		classBodyDeclarations.add(
				new ConstructorDeclaration(null,null,new ConstructorModifiers(ConstructorModifier.PUBLIC), 
						new ConstructorDeclarator(null,getMetaType().getNameIdentifier(), new FormalParameters(
								new FormalParameter(null, target.getClassOrInterfaceType(),true, new VariableDeclaratorId(partsId))))
				, null, new ConstructorBody(new SuperExplicitConstructorInvocation(null, args ),null))
				);
		
		
		
		
		// workaround, type declaration sadly handles null interfaces, but not empty ones (it generates an "implements" followed by nothing
		InterfaceTypes interfaceTypes = getMetaType().getInterfaceTypes();
		Interfaces interfaces ;
		if (interfaceTypes.size() == 0 ) interfaces = null;
		else interfaces = new Interfaces(interfaceTypes);
		
		return new NormalClassDeclaration(null, new ClassModifiers(ClassModifier.PUBLIC), getMetaType().getNameIdentifier(), null, new Super(partList), interfaces, new ClassBody(classBodyDeclarations) );
	}
	
	
	
}
